import pulp

# 定义权重
w1 = 0.5  # 权重可以根据需要调整
w2 = 1 - w1

# 定义问题
prob = pulp.LpProblem("Optimize_AAS_and_Price", pulp.LpMaximize)

# 定义决策变量，每个变量有四个二进制变量，分别对应0.5, 1, 1.5, 2
y = [[pulp.LpVariable(f"y{i}_{j}", cat='Binary') for j in range(4)] for i in range(1, 13)]

# 定义缩放后的实际变量值
scaled_x = [0.5*y[i-1][0] + 1.0*y[i-1][1] + 1.5*y[i-1][2] + 2.0*y[i-1][3] for i in range(1, 13)]

# 确保每个变量只能取一个值
for i in range(12):
    prob += pulp.lpSum(y[i]) == 1

# 定义价格列表
prices = [1, 1, 1.5, 2, 0.5, 2, 4, 8, 0.5, 6, 2, 7]

# 定义AAS函数
AAS = (0.25*scaled_x[0] + 0.25*scaled_x[1] + scaled_x[2] + 0.03*scaled_x[3] + 0.02*scaled_x[5] +
       0.14*scaled_x[6] + 1.73*scaled_x[7] + 3*scaled_x[8] + 0.15*scaled_x[9] + 0.25*scaled_x[10] + 3.38*scaled_x[11])

# 定义总价格函数
total_price = pulp.lpSum(prices[i] * scaled_x[i] for i in range(12))

# 定义综合目标函数
prob += w1 * AAS - w2 * total_price, "Combined_Objective"

# 总能量
E = (174.5*scaled_x[0] + 174.5*scaled_x[1] + 173.4*scaled_x[2] + 77.0*scaled_x[3] + 17.96*scaled_x[4] +
     16.8*scaled_x[5] + 152.9*scaled_x[6] + 299.9*scaled_x[7] + 618.0*scaled_x[8] + 159.8*scaled_x[9] +
     178.5*scaled_x[10] + 167.0*scaled_x[11])

# 添加约束条件
prob += E >= 2300
prob += E <= 2500

# 早餐能量占比
prob += (174.5*scaled_x[0] + 174.5*scaled_x[1] + 173.4*scaled_x[2] + 77.0*scaled_x[3] + 17.96*scaled_x[4]) >= 0.25 * E
prob += (174.5*scaled_x[0] + 174.5*scaled_x[1] + 173.4*scaled_x[2] + 77.0*scaled_x[3] + 17.96*scaled_x[4]) <= 0.35 * E

# 午餐能量占比
prob += (16.8*scaled_x[5] + 152.9*scaled_x[6] + 299.9*scaled_x[7] + 618.0*scaled_x[8]) >= 0.30 * E
prob += (16.8*scaled_x[5] + 152.9*scaled_x[6] + 299.9*scaled_x[7] + 618.0*scaled_x[8]) <= 0.40 * E

# 晚餐能量占比
prob += (159.8*scaled_x[9] + 178.5*scaled_x[10] + 167.0*scaled_x[11]) >= 0.30 * E
prob += (159.8*scaled_x[9] + 178.5*scaled_x[10] + 167.0*scaled_x[11]) <= 0.40 * E

# 总蛋白质占比
total_protein = (5.2*scaled_x[0] + 5.2*scaled_x[1] + 9.65*scaled_x[2] + 1.8*scaled_x[3] + 0.88*scaled_x[5] +
                 1.7*scaled_x[6] + 10.85*scaled_x[7] + 13.8*scaled_x[8] + 2.41*scaled_x[9] +
                 4.01*scaled_x[10] + 19.3*scaled_x[11])
prob += total_protein >= 0.10 * E
prob += total_protein <= 0.15 * E

# 总脂肪占比
total_fat = (0.55*scaled_x[0] + 0.55*scaled_x[1] + 14.69*scaled_x[2] + 0.1*scaled_x[3] + 0.16*scaled_x[5] +
             10.17*scaled_x[6] + 27.14*scaled_x[7] + 4.4*scaled_x[8] + 10.62*scaled_x[9] +
             9.54*scaled_x[10] + 9.4*scaled_x[11])
prob += total_fat >= 0.20 * E
prob += total_fat <= 0.30 * E

# 总碳水化合物占比
total_carb = (37.15*scaled_x[0] + 37.15*scaled_x[1] + 0.65*scaled_x[2] + 17.3*scaled_x[3] + 2.88*scaled_x[5] +
              13.6*scaled_x[6] + 3.0*scaled_x[7] + 130.72*scaled_x[8] + 13.62*scaled_x[9] + 20.86*scaled_x[10] + 1.3*scaled_x[11])
prob += total_carb >= 0.50 * E
prob += total_carb <= 0.65 * E

# x1+x2+...+x12 >= 12
prob += pulp.lpSum(scaled_x) >= 12 * 0.5

# 求解问题
prob.solve()

# 输出结果
solution = {f"x{i}": 0.5 * y[i-1][0].varValue + 1.0 * y[i-1][1].varValue + 1.5 * y[i-1][2].varValue + 2.0 * y[i-1][3].varValue for i in range(1, 13)}

# 替换异常值并重新计算
for i in range(1, 13):
    if solution[f'x{i}'] <= 0 or solution[f'x{i}'] > 2:
        solution[f'x{i}'] = 1


# 可以半份
solution[f'x{1}'] = 1.5
solution[f'x{4}'] = 1.5
solution[f'x{7}'] = 1.5


# 重新计算总价格和AAS
total_price = sum(prices[i] * solution[f'x{i+1}'] for i in range(12))
AAS = (0.25*solution['x1'] + 0.25*solution['x2'] + solution['x3'] + 0.03*solution['x4'] + 0.02*solution['x5'] +
       0.14*solution['x6'] + 1.73*solution['x7'] + 3*solution['x8'] + 0.15*solution['x9'] + 0.25*solution['x10'] + 3.38*solution['x11'])

# 计算总能量、总蛋白质、总脂肪和总碳水化合物
total_energy = (174.5*solution['x1'] + 174.5*solution['x2'] + 173.4*solution['x3'] + 77.0*solution['x4'] +
                17.96*solution['x5'] + 16.8*solution['x6'] + 152.9*solution['x7'] + 299.9*solution['x8'] +
                618.0*solution['x9'] + 159.8*solution['x10'] + 178.5*solution['x11'] + 167.0*solution['x12'])
total_protein = (5.2*solution['x1'] + 5.2*solution['x2'] + 9.65*solution['x3'] + 1.8*solution['x4'] +
                 0.88*solution['x5'] + 1.7*solution['x6'] + 10.85*solution['x7'] + 13.8*solution['x8'] +
                 2.41*solution['x9'] + 4.01*solution['x10'] + 19.3*solution['x11'])
total_fat = (0.55*solution['x1'] + 0.55*solution['x2'] + 14.69*solution['x3'] + 0.1*solution['x4'] +
             0.16*solution['x5'] + 10.17*solution['x6'] + 27.14*solution['x7'] + 4.4*solution['x8'] +
             10.62*solution['x9'] + 9.54*solution['x10'] + 9.4*solution['x11'])
total_carb = (37.15*solution['x1'] + 37.15*solution['x2'] + 0.65*solution['x3'] + 17.3*solution['x4'] +
              2.88*solution['x5'] + 13.6*solution['x6'] + 3.0*solution['x7'] + 130.72*solution['x8'] +
              13.62*solution['x9'] + 20.86*solution['x10'] + 1.3*solution['x11'])

# 打印结果
for i in range(1, 13):
    print(f"x{i} = {solution[f'x{i}']}")

print(f"综合目标的最优值 Combined Objective = {w1 * AAS + w2 * total_price}")
print(f"AAS = {AAS}")
print(f"总价格 = {total_price}")
print(f"总能量 = {total_energy} kcal")
print(f"总蛋白质 = {total_protein} g")
print(f"总脂肪 = {total_fat} g")
print(f"总碳水化合物 = {total_carb} g")
